iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 26
0
Modern Web

Déjà-vu ? 要 Vue 過才知道系列 第 26

Vue 元件傳遞資料的命名坑與型別

  • 分享至 

  • xImage
  •  

最會偽裝的就是變數,變來變去常讓人分不清是變到哪裡去了...根本是忍者!

這幾天寫的都是與元件相關,元件的重要有一部分是因為它可以為我們省不少力,以前接觸 PHP 也是會將也面拆成好幾大塊,然後在引入整個頁面中,只不過當時需要把完整的整頁 HTML 碼拆開,且還要花力氣把 CSS 和 HTML 分離,實在是有點混亂。而現在的前端框架已經能做到將版面拆分成模塊,再將模塊拆成元件,這樣元件再組合起來,複用性就增加了不少。

在 Vue 官網裡,雖然使用方式寫著很清楚的,但是有時候在學習的時候無法馬上抓到精華,往往是自己實作時會出現一大堆問題,有時解 Bug 會解到抓頭,但解完時又是向學習之路邁前一步。在真的解不出來的時候,回頭看官網的資料往往是可以讓迷霧中的自己找到出路,然後輕嘆一聲,唉,之前怎麼沒看懂呢!?

有時候在看課程或範例時,會發現所有無論在父元件或子元件、屬性名常常是統一命名,這樣當然不會出現問題,但是現實的實作我們會依變數的意義來命名,這時出現的錯誤就很難找出來,所以看完課程或解說,自己重新寫一遍,且把所有的屬性或變數名稱換掉,實作出來沒有出錯才算是真的瞭解其運作。

Debug 時出現的錯誤訊息有時只能給一個方向,甚至會是一種混淆(或是自己沒有真的看懂...),有時這些錯誤可能是在某些區域不能備註(commend)的原因所致,遇到這種狀況最好先將多餘的程式碼去掉(不是備註),再用最簡單的方式一一測試,比較容易找到問題。

不接受大寫的 HTML 標籤

以最近遇到的問題為例,要將父元件的某一屬性值,以動態的方式傳到子元件裡,除了在 HTML 裡的模版標籤裡加上屬性外,還要在子主件的props上註冊,並將其放到子元件的模版template中才算完成。在官網裡有說到Prop 的大小寫 (camelCase vs kebab-case),原因是在 HTML 的命名規則裡,是不允許駝峰式的「大寫」,需要將其改成小寫,或是兩個單字中間以-隔開。以官網的範例:

<!-- 在 HTML 中是 kebab-case 的 -->
<blog-post post-title="hello!"></blog-post>
<script>
  Vue.component('blog-post', {
    // 在 JavaScript 中是 camelCase 的
    props: ['postTitle'],
    template: '<h3>{{ postTitle }}</h3>'
  })
</script>

所以同一個屬性名在propstemplate的命名是postTitle,在 HTML 的 DOM 標籤裡就需要寫成post-title。我們都習慣一致的名稱,所以在這部分很容易沒那個習慣或忘了寫成 DOM 標籤格式而出現錯誤。

元件傳遞資料的型別

要將父元件的資料傳遞過來子元件,可以透過 props,資料型別也可以是字串、物件、布林值、函式甚至是promise,如果以全域元件的方式,我們可以來看一下範例:

在父元件裡初始化不同型別的資料,在子元件裡我們先在模版裡插入代表不同型別的資料變數,接著在 HTML 裡放入以子元件為標籤的模版標籤<text-bloc>,並以 DOM 的命名方式把資料變數修改成屬性名並綁定資料,值則為父元件的變數。

在子元件的 Props 以陣列形式加入(註冊)這些資料變數,形同告知子元件,有這些值要從父元件接收過來,這樣就算成功的把父元件傳遞到子元件了。如果是陣列,我們也可以利用v-for將陣列裡的值一一取出。

<div id="app">
  <div>{{ msg }}</div>
  <text-bloc
    :props-str="propsStr"
    :props-num="postCode"
    :props-boo="isVegan"
    :props-arr="foods"
    :props-obj="boos"
  ></text-bloc>
</div>

<script>
// 子元件
  Vue.config.errorHandler = function (err, vm, info) {};
  Vue.component('text-bloc', {
    props: ['propsStr', 'propsNum', 'propsBoo', 'propsArr', 'propsObj'],
    template: `
      <div>
        <div>{{ 'City: ' + propsStr }}</div>
        <div>{{ 'post Code: ' + propsNum }}</div>
        <div>{{ 12 + propsNum }}</div>
        <div>{{ 'isVegan: ' + propsBoo }}</div>
        <ul>
          <li v-for="(item,index) in propsArr" :key='index'>{{item}}</li>
        </ul>
      <div>{{ propsObj.name}} : {{propsObj.age }}</div>
    </div>
      `,
  });
// 父元件
  const vm = new Vue({
    el: '#app',
    data: {
      msg: '父元件中的資料內容',
      propsStr: 'Paris',
      postCode: 75,
      isVegan: true,
      foods: ['cafe', 'wine', 'apple'],
      boos: {
        name: 'Tracy',
        age: 42,
      },
    },
  });
</script>

週日結束了,鐵人賽只剩四天,看來是無法全部寫完 vue.js 的基本功能,況且 Vue3 已經發布,接下來應該是傾向學習新版的寫法了。

Prop 類型 — Vue.js

每日一句法文有益身心:Bien fait ! --> ㄅㄧㄤ.飛! --> 幹的好!


上一篇
Vue 元件間的資料傳遞 Props
下一篇
子元件向父元件傳值與訊息
系列文
Déjà-vu ? 要 Vue 過才知道30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言